package com.lanchetech.service.impl;


import com.lanchetech.bean.request.SpuPageReq;
import com.lanchetech.bean.response.PackageResp;
import com.lanchetech.bean.response.SpuResp;
import com.lanchetech.bean.vo.NumberVO;
import com.lanchetech.bean.vo.PackageSkuVO;
import com.lanchetech.dao.*;
import com.lanchetech.entity.*;
import com.lanchetech.service.DaoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


@Service
public class DaoServiceImpl implements DaoService {

    @Autowired
    CategoryMapper categoryMapper;

    @Autowired
    BrandMapper brandMapper;

    @Autowired
    FreightMapper freightMapper;

    @Autowired
    SkuMapper skuMapper;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    SpuMapper spuMapper;

    @Autowired
    SpuCommissionMapper spuCommissionMapper;

    @Autowired
    PackagesMapper packagesMapper;

    @Autowired
    PackageSkuMapper packageSkuMapper;

    @Autowired
    UserMapper userMapper;

    @Autowired
    LogisticsCompanyMapper logisticsCompanyMapper;

    @Autowired
    CouponMapper couponMapper;

    @Autowired
    ColumnsMapper columnsMapper;

    @Autowired
    CourseMapper courseMapper;

    @Autowired
    HipoConfigMapper hipoConfigMapper;

    @Autowired
    LotteryMapper lotteryMapper;

    @Autowired
    ShopMapper shopMapper;

    @Autowired
    AppointmentSettingMapper appointmentSettingMapper;

    @Autowired
    SpuCourierAmountMapper spuCourierAmountMapper;

    @Autowired
    JobMapper jobMapper;

    @Autowired
    IndustryMapper industryMapper;

    @Autowired
    FarmProductMapper farmProductMapper;

    @Autowired
    MsgUserMapper msgUserMapper;

    @Autowired
    UserTaskMapper userTaskMapper;

    @Autowired
    FarmUserMapper farmUserMapper;

    @Autowired
    SaplingMapper saplingMapper;

    @Autowired
    OrdersMapper ordersMapper;

    @Autowired
    OrderSkuMapper orderSkuMapper;

    @Autowired
    MerchantRoleMapper merchantRoleMapper;

    @Autowired
    TenantMapper tenantMapper;

    @Autowired
    BlogMapper blogMapper;

    @Autowired
    CommonCommentMapper commonCommentMapper;

    @Autowired
    TagCategoryMapper tagCategoryMapper;

    @Autowired
    AdminMapper adminMapper;

    @Autowired
    IdentityMapper identityMapper;

    @Override
    public Map<Long, Category> getCategoryMap(List<Long> ids) {
        List<Category> list = categoryMapper.findAllByIds(ids);
        Map<Long, Category> map = new HashMap<>();
        list.stream().forEach(item -> map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, Brand> getBrandMap(List<Long> ids) {
        List<Brand> list = brandMapper.findAllByIds(ids);
        Map<Long, Brand> map = new HashMap<>();
        list.stream().forEach(item -> map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, Freight> getFreightMap(List<Long> ids) {
        List<Freight> list = freightMapper.findAllByIds(ids);
        Map<Long, Freight> map = new HashMap<>();
        list.stream().forEach(item -> map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, List<Sku>> getSkuListMap(List<Long> spuIds) {
        List<Sku> skuList = skuMapper.findAllBySpuIds(spuIds);
        Map<Long, List<Sku>> skuListMap = new HashMap<>();
        skuList.stream().forEach((item) -> {
            if (skuListMap.containsKey(item.getSpuId())) {
                skuListMap.get(item.getSpuId()).add(item);
            } else {
                List<Sku> list = new ArrayList<>();
                list.add(item);
                skuListMap.put(item.getSpuId(), list);
            }
        });
        return skuListMap;
    }

    @Override
    public Map<Long, Spu> getSpuMap(List<Long> ids) {
        List<Spu> list = spuMapper.findAllByIds(ids);
        Map<Long, Spu> map = new HashMap<>();
        list.stream().forEach(item -> map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, Sku> getSkuMap(List<Long> ids) {
        List<Sku> list = skuMapper.findAllByIds(ids);
        Map<Long, Sku> map = new HashMap<>();
        list.stream().forEach(item -> map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, User> getUserMap(List<Long> ids) {
        List<User> list = userMapper.findAllByUserIds(removeRepeat(ids));
        Map<Long, User> map = new HashMap<>();
        list.stream().forEach(item -> map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, SpuCommission> getSpuCommissionMap(List<Long> spuIds) {
        List<SpuCommission> list = spuCommissionMapper.findAllBySpuIds(spuIds);
        Map<Long, SpuCommission> map = new HashMap<>();
        list.stream().forEach(item -> map.put(item.getSpuId(), item));
        return map;
    }

    @Override
    public List<Spu> findAllLikeSpu(Long categoryId) {
        ValueOperations<String, List<Spu>> operations = redisTemplate.opsForValue();
        String key = "LikeSpu:" + categoryId;
        List<Spu> result = operations.get(key);
        if (result != null) {
            return result;
        }
        result = spuMapper.findAllLikeSpu(categoryId);
        operations.set(key, result, 1, TimeUnit.DAYS);
        return result;
    }

    @Override
    public PackageResp getPackageDetail(Long id) {
        PackageResp packageResp = new PackageResp();
        packageResp.setPackages(packagesMapper.selectByPrimaryKey(id));
        List<PackageSku> packageSkuList = packageSkuMapper.findAllByActivityId(id);
        Map<Long, Sku> skuMap = getSkuMap(packageSkuList.stream().map(PackageSku::getSkuId).collect(Collectors.toList()));
        Map<Long, Spu> spuMap = getSpuMap(packageSkuList.stream().map(PackageSku::getSpuId).collect(Collectors.toList()));
        List<PackageSkuVO> packageSkuVOList = new ArrayList<>();
        packageSkuList.stream().forEach(item -> packageSkuVOList.add(PackageSkuVO.builder()
                .id(item.getId())
                .activityId(item.getActivityId())
                .spuId(item.getSpuId())
                .skuId(item.getSkuId())
                .activityPrice(item.getPrice())
                .count(item.getCount())
                .createdAt(item.getCreatedAt())
                .image(skuMap.get(item.getSkuId()).getImage())
                .costPrice(skuMap.get(item.getSkuId()).getCostPrice())
                .price(skuMap.get(item.getSkuId()).getPrice())
                .stock(skuMap.get(item.getSkuId()).getStock())
                .stockUnit(skuMap.get(item.getSkuId()).getStockUnit())
                .specNames(skuMap.get(item.getSkuId()).getSpecNames())
                .specValues(skuMap.get(item.getSkuId()).getSpecValues())
                .name(spuMap.get(item.getSpuId()).getName())
                .build()));
        packageResp.setPackageSkuVOList(packageSkuVOList);
        return packageResp;
    }

    @Override
    public Map<String, LogisticsCompany> getLogisticsCompanyMap() {
        List<LogisticsCompany> list = logisticsCompanyMapper.findAll();
        Map<String, LogisticsCompany> map = new HashMap<>();
        list.stream().forEach(item -> map.put(item.getCode(), item));
        return map;
    }

    @Override
    public Map<Long, Coupon> getCouponMap(List<Long> ids) {
        List<Coupon> list = couponMapper.findAllByIds(removeRepeat(ids));
        Map<Long, Coupon> map = new HashMap<>();
        list.stream().forEach(item -> map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, Columns> getColumnMap(List<Long> ids) {
        List<Columns> list = columnsMapper.findAllByIds(removeRepeat(ids));
        Map<Long, Columns> map = new HashMap<>();
        list.stream().forEach(item -> map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, Course> getCourseMap(List<Long> ids) {
        List<Course> list = courseMapper.findAllByIds(removeRepeat(ids));
        Map<Long, Course> map = new HashMap<>();
        list.stream().forEach(item -> map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<String, String> getHipoConfigMap() {
        ValueOperations<String, Map<String, String>> operations = redisTemplate.opsForValue();
        String key = "HipoConfig";
        Map<String, String> map = operations.get(key);
        if (map != null) {
            return map;
        } else {
            List<HipoConfig> hipoConfigs = hipoConfigMapper.findAll();
            map = new HashMap<>();
            for (HipoConfig item : hipoConfigs) {
                map.put(item.getName(), item.getValue());
            }
            operations.set("HipoConfig", map);
        }
        return map;
    }

    @Override
    public String getHipoConfigValue(String name) {
        ValueOperations<String, Map<String, String>> operations = redisTemplate.opsForValue();
        String key = "HipoConfig";
        Map<String, String> map = operations.get(key);
        if (map != null) {
            return map.get(name);
        } else {
            return hipoConfigMapper.findValueByName(name);
        }
    }

    @Override
    public BigDecimal getHipoConfigNumber(String name) {
        ValueOperations<String, Map<String, String>> operations = redisTemplate.opsForValue();
        String key = "HipoConfig";
        Map<String, String> map = operations.get(key);
        if (map != null) {
            return new BigDecimal(map.get(name));
        } else {
            return new BigDecimal(hipoConfigMapper.findValueByName(name));
        }
    }

    public static List removeRepeat(List<Long> list) {
        HashSet set = new HashSet(list);
        list.clear();
        list.addAll(set);
        return list;
    }

    @Override
    public Map<Long, Lottery> getLotteryMap(List<Long> ids) {
        List<Lottery> list = lotteryMapper.findAllByIds(removeRepeat(ids));
        Map<Long, Lottery> map = new HashMap<>();
        list.stream().forEach(item -> map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, Shop> getShopMap(List<Long> ids) {
        List<Shop> list = shopMapper.findAllByIds(removeRepeat(ids));
        Map<Long, Shop> map = new HashMap<>();
        list.stream().forEach(item -> map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, AppointmentSetting> getAppointmentSettingMap(List<Long> ids) {
        List<AppointmentSetting> list = appointmentSettingMapper.findAllByIds(removeRepeat(ids));
        Map<Long, AppointmentSetting> map = new HashMap<>();
        list.stream().forEach(item -> map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, AppointmentSetting> getAppointmentSettingMapBySpuIds(List<Long> ids) {
        List<AppointmentSetting> list = appointmentSettingMapper.findAllBySpuIds(removeRepeat(ids));
        Map<Long, AppointmentSetting> map = new HashMap<>();
        list.stream().forEach(item -> map.put(item.getSpuId(), item));
        return map;
    }

    @Override
    public Map<Long, SpuCourierAmount> getSpuCourierAmount(List<Long> spuIds) {
        List<SpuCourierAmount> list = spuCourierAmountMapper.findAllBySpuIds(removeRepeat(spuIds));
        Map<Long, SpuCourierAmount> map = new HashMap<>();
        list.stream().forEach(item -> map.put(item.getSpuId(), item));
        return map;
    }

    @Override
    public Map<Long, Job> getJobMap(List<Long> ids) {
        List<Job> list = jobMapper.findAllByIds(removeRepeat(ids));
        Map<Long, Job> map = new HashMap<>();
        list.stream().forEach(item -> map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, Industry> getIndustryMap(List<Long> ids) {
        List<Industry> list = industryMapper.findAllByIds(removeRepeat(ids));
        Map<Long, Industry> map = new HashMap<>();
        list.stream().forEach(item->map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, FarmProduct> getFarmProductMap(List<Long> ids) {
        List<FarmProduct> list = farmProductMapper.findAllByIds(removeRepeat(ids));
        Map<Long, FarmProduct> map = new HashMap<>();
        list.stream().forEach(item->map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, MsgUser> getMsgUserMap(List<Long> ids) {
        List<MsgUser> list = msgUserMapper.findAllByIds(ids);
        Map<Long, MsgUser> map = new HashMap<>();
        list.stream().forEach(item->map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, UserTask> getUserTaskMap(List<Long> ids, Long userId,Date date) {
        List<UserTask> list = userTaskMapper.findAllByIdsAndUserId(ids,userId,date);
        Map<Long, UserTask> map = new HashMap<>();
        list.stream().forEach(item->map.put(item.getTaskId(), item));
        return map;
    }

    @Override
    public Map<Long, FarmUser> getFarmUserMap(List<Long> userIds) {
        List<FarmUser> list = farmUserMapper.findAllByUserIds(userIds);
        Map<Long, FarmUser> map = new HashMap<>();
        list.stream().forEach(item->map.put(item.getUserId(), item));
        return map;
    }
    @Override
    public Map<Long, Sapling> getSaplingMap() {
        List<Sapling> list = saplingMapper.findAllList();
        Map<Long, Sapling> map = new HashMap<>();
        list.stream().forEach(item->map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, Orders> getOrdersMap(List<Long> ordersIds) {
        List<Orders> list = ordersMapper.findAllByOrdersIds(ordersIds);
        Map<Long,Orders> map = new HashMap<>();
        list.stream().forEach(item->map.put(item.getId(),item));
        return map;
    }


    @Override
    public Map<Long, MerchantRole> getMerchantRoleMap(List<Long> ids) {
        List<MerchantRole> list = merchantRoleMapper.findAllByIds(removeRepeat(ids));
        Map<Long, MerchantRole> map = new HashMap<>();
        list.stream().forEach(item->map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, Tenant> getTenantMap(List<Long> ids) {
        List<Tenant> list = tenantMapper.findAllByIds(removeRepeat(ids));
        Map<Long, Tenant> map = new HashMap<>();
        list.stream().forEach(item->map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, Blog> getBlogMap(List<Long> ids) {
        List<Blog> list = blogMapper.findAllByIds(removeRepeat(ids));
        Map<Long, Blog> map = new HashMap<>();
        list.stream().forEach(item->map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, CommonComment> getCommonCommentMap(List<Long> ids) {
        List<CommonComment> list = commonCommentMapper.findAllByIds(removeRepeat(ids));
        Map<Long, CommonComment> map = new HashMap<>();
        list.stream().forEach(item->map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, TagCategory> getTagCategoryMap(List<Long> ids) {
        List<TagCategory> list = tagCategoryMapper.findAllByIds(removeRepeat(ids));
        Map<Long, TagCategory> map = new HashMap<>();
        list.stream().forEach(item->map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, Admin> getAdminMap(List<Long> adminIds) {
        List<Admin> list = adminMapper.findAllByIds(removeRepeat(adminIds));
        Map<Long, Admin> map = new HashMap<>();
        list.stream().forEach(item->map.put(item.getId(), item));
        return map;
    }

    @Override
    public Map<Long, OrderSku> getOrderSkuMap(List<Long> collect) {
        List<OrderSku> list = orderSkuMapper.findAllByIds(removeRepeat(collect));
        Map<Long, OrderSku> map = new HashMap<>();
        list.stream().forEach(item->map.put(item.getId(), item));
        return map;
    }

    @Override
    public List<SpuResp> likeSpu(SpuPageReq req) {
        List<SpuResp> spuResps = spuMapper.likeSpu(req);
        return spuResps;
    }
}